#include "stm32f10x.h"                  // Device header
#include "W25Q64.h"
#include "SPI_Periph.h"

void W25Q64_Init(void)
{
	SPI_Periph_Init();
}

void W25Q64_ReadID(u8 *MID,u16 *DID)
{
	SPI_Periph_Start();
	SPI_Periph_SwapByte(W25Q64_JEDEC_ID);
	*MID = SPI_Periph_SwapByte(0xff);
	*DID = SPI_Periph_SwapByte(0xff);
	*DID <<= 8;
	*DID |= SPI_Periph_SwapByte(0xff);
	SPI_Periph_Stop();
}

void W25Q64_WriteEnable(void)
{
	SPI_Periph_Start();
	SPI_Periph_SwapByte(W25Q64_WRITE_ENABLE);
	SPI_Periph_Stop();
}

void W25Q64_WaitBusy(void)
{
	u32 Timeout = 100000;
	SPI_Periph_Start();
	SPI_Periph_SwapByte(W25Q64_READ_STATUS_REGISTER_1);
	while((SPI_Periph_SwapByte(0xff) & 0x01) == 0x01) {
		Timeout--;
		if(Timeout == 0) {
			break;
		}
	}
	SPI_Periph_Stop();
}

void W25Q64_PageProgram(u32 addr,u8 *DataArray,u16 count)
{
	u16 i;
	W25Q64_WaitBusy();
	W25Q64_WriteEnable();
	SPI_Periph_Start();
	SPI_Periph_SwapByte(W25Q64_PAGE_PROGRAM);
	SPI_Periph_SwapByte(addr >> 16);
	SPI_Periph_SwapByte(addr >> 8);
	SPI_Periph_SwapByte(addr);
	for(i=0;i<count;i++) {
		SPI_Periph_SwapByte(DataArray[i]);
	}
	SPI_Periph_Stop();
}

void W25Q64_SectorErase(u32 addr)
{
	W25Q64_WaitBusy();
	W25Q64_WriteEnable();
	SPI_Periph_Start();
	SPI_Periph_SwapByte(W25Q64_SECTOR_ERASE_4KB);
	SPI_Periph_SwapByte(addr >> 16);
	SPI_Periph_SwapByte(addr >> 8);
	SPI_Periph_SwapByte(addr);
	SPI_Periph_Stop();
}

void W25Q64_ReadData(u32 addr,u8 *DataArray,u32 count)
{
	u32 i;
	W25Q64_WaitBusy();
	SPI_Periph_Start();
	SPI_Periph_SwapByte(W25Q64_READ_DATA);
	SPI_Periph_SwapByte(addr >> 16);
	SPI_Periph_SwapByte(addr >> 8);
	SPI_Periph_SwapByte(addr);
	for(i=0;i<count;i++) {
		DataArray[i] = SPI_Periph_SwapByte(0xff);
	}
	SPI_Periph_Stop();
}
